#include "Attack.h"
#include "Player.h"
#include "Monster.h"
#include <ctime>    
#include <cstdlib>
#include <vector>

//controller feel free to modify to suite your needs.

void Attack::attack(Player* p, Monster* m, int a)
{
	int chanceToEvade = m->getMonsterStats().getAgility() / 50;  // every 50 pts of agility gives 1% chance to evade.
	
	vector<bool> table(100, false); 
	
	srand( time(0) );
	for(int i = 0; i < chanceToEvade; i++)   
	{
		int r = rand() % 100;    // mark random number between 0 to 99 
		table[r] = true;      
	}
	
	for(int i = 0; i < chanceToEvade; i++)
	{
		int r = rand() % 100;    // guess number between 0 to 99 
		if( table[r] == true )   // if guess correctly, then monster evades attack, so exit 
		{
			cout << "monster evades attack" << endl;
			return;
		}
	}
	
	int attackTypeBaseDamage = 0;      // assume default attack type base damage is 0.   
	
	AttackType anAttackType;
	if( p->getAttackType(a, anAttackType) )  // if caller chooses a valid index a
	{
		int attackActionCost   = anAttackType.getActionPointsCost();
		int playerActionPoints = p->getPlayerStats().getActionPoints();
		  
		if( playerActionPoints >= attackActionCost )  // if player has enough AP to peform attack
		{
			int playerActionPointsAfterAttack = playerActionPoints - attackActionCost;
			p->getPlayerStats().setActionPoints( playerActionPointsAfterAttack );
			
			attackTypeBaseDamage = anAttackType.getBaseDamage();  // apply attack damage, otherwise defaults to 0.
		}			
	}

	int playerBonusStat = 0;
	if( p->getCharClass() == WARRIOR )
		playerBonusStat = p->getPlayerStats().getStrength();
	else if( p->getCharClass() == WIZARD )
		playerBonusStat = p->getPlayerStats().getIntelligence();
	else 
		playerBonusStat = p->getPlayerStats().getConcentration();
	
	int playerDamage   = p->getPlayerStats().getDamage();
	int weightedDamage = playerDamage + attackTypeBaseDamage + (playerBonusStat / 20);   // +5% bonus damage of player's special stat
	int mitigateDamage = weightedDamage - m->getMonsterStats().getArmor();
	
	int monsterHitPointAfterAttack = m->getMonsterStats().getHitPoints() - mitigateDamage;
	m->getMonsterStats().setHitPoints( monsterHitPointAfterAttack );
	
	if( monsterHitPointAfterAttack <= 0 )
		m->setDead( true );
}

void Attack::attack(Monster* m, Player* p)
{
	int chanceToEvade = p->getPlayerStats().getAgility() / 50;  // every 50 pts of agility gives 1% chance to evade.
	
	vector<bool> table(100, false); 
	
	srand( time(0) );
	for(int i = 0; i < chanceToEvade; i++)   
	{
		int r = rand() % 100;    // mark random number between 0 to 99
		table[r] = true;      
	}
	
	for(int i = 0; i < chanceToEvade; i++)
	{
		int r = rand() % 100;    // guess number between 0 to 99
		if( table[r] == true )   // if guess correctly, then player evades attack, so exit
		{
			cout << "player evades attack" << endl;
			return;
		}
	}

	int attackTypeBaseDamage = 0;      // assume default attack type base damage is 0.   
	
	int r = rand() % m->getNumAttacks();  // random attack type r
	
	AttackType anAttackType;
	if( m->getAttackType(r, anAttackType) )  // will probably be true all the time, just in case vector.size() = 0;
	{
		int attackActionCost    = anAttackType.getActionPointsCost();
		int monsterActionPoints = m->getMonsterStats().getActionPoints();
		  
		if( monsterActionPoints >= attackActionCost )  // if monster has enough AP to peform attack
		{
			int monsterActionPointsAfterAttack = monsterActionPoints - attackActionCost;
			m->getMonsterStats().setActionPoints( monsterActionPointsAfterAttack );
			
			attackTypeBaseDamage = anAttackType.getBaseDamage();  // apply attack damage, otherwise defaults to 0.
		}			
	}
	
	int weightedDamage = m->getMonsterStats().getDamage() + attackTypeBaseDamage; 
	int mitigateDamage = weightedDamage - p->getPlayerStats().getArmor();
	
	int playerHitPointAfterAttack = p->getPlayerStats().getHitPoints() - mitigateDamage;
	p->getPlayerStats().setHitPoints( playerHitPointAfterAttack );
	
	if( playerHitPointAfterAttack <= 0 )
		p->setDead( true );
}